#include "config.h"
#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (GETTEXT_PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#endif
#ifndef ENABLE_NLS
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

#include "config.h"
#include "NLS.h"
#include "CommandLine.h"
#include "TimeConverter.h"
#include "MIMEScanner.h"
#include "Url.h"
#include "MonitorFactory.h"
#include "QueryHistory.h"
#include "ViewHistory.h"
#include "ModuleFactory.h"
#include "PinotUtils.h"
#include "mainWindow.hh"

#include "DocumentInfo.h"
#include "QueryProperties.h"
#include "MonitorInterface.h"
#include "MonitorHandler.h"
#include "PinotSettings.h"
#include "UIThreads.hh"

#include "simplerender.hh"
#include "simple-icon-view.hh"
#include <glibmm/ustring.h>
#include <iostream>

extern "C"
{
#include<gtk/gtk.h>
#include<nbtk/nbtk.h>
#include<clutter/clutter.h>
#include<clutter-gtk/clutter-gtk.h>
}

#include<stdlib.h>

using namespace std;
using namespace Glib;

enum { B = 0, KB, MB, GB, TB };
gchar * size_end[] = { _("B") , _("KB"), _("MB"), _("GB"), _("TB"), NULL};
typedef enum {GOOGLE=0, WIKI, BING, DESKTOP,TOTAL_NUMBER} ENGINE_UI;

struct model_view_combine{
        ENGINE_UI type;
        ClutterModel * model;
        NbtkWidget   * icon_view;
        NbtkWidget   * button;
        gchar  * result_number_string; 
        gint result_number;   
}model_view[TOTAL_NUMBER];
ENGINE_UI current;
gchar * button_label[] = {_("Google "),_("Wiki "),_("Bing "),_("Desktop "),NULL};
static gboolean need_reload = FALSE;

static NbtkWidget * scroll;
static NbtkWidget *result_num_label;
static NbtkWidget *page_num_label;
static NbtkWidget *button_prev; 
static NbtkWidget *button_next; 
static NbtkWidget * sort_result_table;
/*function prototype*/
          //UI
static void set_sort (NbtkButton *button, gpointer data);
static gint sort_bydate (ClutterModel *model, const GValue *a, const GValue *b, gpointer user_data);
static gint sort_bysize (ClutterModel *model, const GValue *a, const GValue *b, gpointer user_data);
static gint sort_bytype (ClutterModel *model, const GValue *a, const GValue *b, gpointer user_data);
static void update_model( ENGINE_UI type, const vector<DocumentInfo> &resultsList , const string &resultsCharset);
static void on_window_destroy(GtkWidget * window , gpointer data);
static void on_findButton_clicked(NbtkButton * button , gpointer data);
static void on_closeButton_clicked(NbtkButton * button , gpointer data);
static void on_prefsButton_clicked(NbtkButton * button , gpointer data); 
static gpointer text_changed  (gpointer user_data);
static void run_search(const QueryProperties &queryProps);
static void  set_result_number_per_page(gint number_page);

          //THREADS
static bool start_thread(WorkerThread *pNewThread, bool inBackground);
static void on_thread_end(WorkerThread *pThread);
static bool on_activity_timeout();

/*prototype end*/

/*threads things*/
static sigc::connection m_timeoutConnection;
static unsigned int m_maxDocsCount;
static PinotSettings &m_settings = PinotSettings::getInstance() ;


class InternalState : public ThreadsManager
      {
                public:
                        InternalState();
                        virtual ~InternalState();

                        // Query
                        unsigned int m_liveQueryLength;
                        // Current actions
                        bool m_browsingIndex;

     } m_state;

InternalState::InternalState( ) :
        ThreadsManager(PinotSettings::getInstance().m_docsIndexLocation, 2, 60, true),
        m_liveQueryLength(0),
        m_browsingIndex(false)
{
        m_onThreadEndSignal.connect(sigc::ptr_fun(on_thread_end));
}

InternalState::~InternalState()
{
}

static void init_thread_environment()
{
  m_state.connect();
}


static bool start_thread(WorkerThread *pNewThread, bool inBackground)
{
	if (m_state.start_thread(pNewThread, inBackground) == false)
	{
		// Delete the object
		delete pNewThread;
		return false;
	}
#ifdef DEBUG
	cout << "mainWindow::start_thread: started thread " << pNewThread->getId() << endl;
#endif

	if (inBackground == false)
	{
		// Enable the activity progress bar
		m_timeoutConnection.block();
		m_timeoutConnection.disconnect();
		m_timeoutConnection = Glib::signal_timeout().connect(sigc::ptr_fun(on_activity_timeout), 1000);
		m_timeoutConnection.unblock();
	}

	return true;
}

static bool on_activity_timeout()
{
	if (m_timeoutConnection.blocked() == false)
	{
	}
#ifdef DEBUG
	else cout << "mainWindow::on_activity_timeout: blocked" << endl;
#endif
       //FIXME:when timeout,do we should stop searching?

	return true;
}





static void on_thread_end(WorkerThread *pThread)
{
	string indexedUrl;
	if (pThread == NULL)
	{
		return;
	}

	string type(pThread->getType());
	string threadStatus(pThread->getStatus());
#ifdef DEBUG
	cout << "mainWindow::on_thread_end: end of thread " << pThread->getId() << endl;
#endif

	// Did the thread fail for some reason ?
	if (threadStatus.empty() == false)
	{
	    /*May be we should do something as before.*/
	}
	else if (type == "QueryingThread")
	{
		set<DocumentInfo> docsToIndex;
		int pageNum = -1;

		QueryingThread *pQueryThread = dynamic_cast<QueryingThread *>(pThread);
		if (pQueryThread == NULL)
		{
			delete pThread;
			return;
		}

		bool wasCorrected = false;
		QueryProperties queryProps(pQueryThread->getQuery(wasCorrected));
		ustring queryName(queryProps.getName());
		string labelName(queryProps.getLabelName());
		ustring engineName(to_utf8(pQueryThread->getEngineName()));
		string resultsCharset(pQueryThread->getCharset());
		set<string> labels;
		const vector<DocumentInfo> &resultsList = pQueryThread->getDocuments();             

                cout<<"###############################"<<endl;
                cout<<"queryName is:"<<queryName<<"labelName :"<<labelName<<"engineName is:"<<engineName<<"charset is:"<<resultsCharset<<endl;


                 //NEED
                    if(engineName=="My Documents")
                       {
                           cout<<"My document engine ****************"<<endl;
                           printf("My document engine ***********result number is %d*****\n",resultsList.size());//TAG
                            update_model( DESKTOP , resultsList, resultsCharset);
                       }                       
                   else if(engineName=="Google")
                       {
                           cout<<"Google engine ****************"<<endl;
                               update_model( GOOGLE , resultsList, resultsCharset);
                       }
                   else if(engineName=="Wikipedia")
                       {
                           cout<<"Wiki engine ****************"<<endl;
                               update_model( WIKI , resultsList, resultsCharset);
                       }
                   else if(engineName=="Bing")
                       {
                           cout<<"Bing! engine ****************"<<endl;
                               update_model( BING , resultsList, resultsCharset);
                       }
                  
	}

	// Delete the thread
	delete pThread;;

	// Any threads left to return ?
	if (m_state.get_threads_count() == 0)
	{
		if (m_timeoutConnection.connected() == true)
		{
			m_timeoutConnection.block();
			m_timeoutConnection.disconnect();
		}
	}
}

static void run_search(const QueryProperties &queryProps)
{
	if (queryProps.isEmpty() == true)
	{
		return;
	}
       set<PinotSettings::IndexProperties>::const_iterator indexIter = m_settings.getIndexes().begin();
        {
#ifdef DEBUG
           cout<<"mainWindow:: "<<from_utf8(m_settings.m_defaultBackend)<<"  "<<from_utf8(indexIter->m_name)<<" "<<indexIter->m_location<<endl;
#endif
             start_thread(new EngineQueryThread(from_utf8(m_settings.m_defaultBackend),
                        from_utf8(indexIter->m_name), indexIter->m_location, queryProps) , false);
        }

  set<ModuleProperties> m_engines;
  m_settings.getSearchEngines(m_engines);

  for (set<ModuleProperties>::iterator engineIter = m_engines.begin(); engineIter != m_engines.end(); ++engineIter)
    {
           
           {
               ustring engineType(to_utf8(engineIter->m_name));
               ustring engineName(to_utf8(engineIter->m_longName));
               ustring enginelocation=engineIter->m_option;
              
              start_thread(new EngineQueryThread(from_utf8(engineType),
                        from_utf8(engineName), enginelocation, queryProps) , false);

            }
    }
}

static void on_window_destroy(GtkWidget * window , gpointer data)
{
   
        if (m_state.get_threads_count() > 0)
        {       
          // Any thread still running ?show dialog to ask user
                m_state.disconnect();
                m_state.stop_threads();
        }
        else
        {
                m_state.disconnect();
        }

#ifdef DEBUG
        printf("mainWindow::on_mainWindow_delete_event: quitting\n");
#endif
     int i;
     for(i=0;i<=DESKTOP;i++)
       {
          g_object_unref(model_view[i].icon_view);
       }
       gtk_main_quit();
}

static void on_findButton_clicked(NbtkButton * button , gpointer data)
{
   NbtkEntry * entry = (NbtkEntry * ) data ;
   const gchar * a = nbtk_entry_get_text(entry);

   if(a == NULL)
        {
         return;  
        }
   if( need_reload == TRUE )
        {
             m_settings.load(PinotSettings::LOAD_ADDON);
             need_reload = FALSE;
             set_result_number_per_page(m_settings.m_maxresultperpagenumbers);
        }
   QueryProperties queryProps(_("Live query"), nbtk_entry_get_text(entry));   
   queryProps.setMaximumResultsCount(m_settings.m_maxresultnumbers);
   run_search(queryProps);
}


gpointer text_changed  (gpointer data)
{
/* for search by character*/
}

static void on_closeButton_clicked(NbtkButton * button , gpointer data)
{
    on_window_destroy( NULL, NULL );
}

static void on_prefsButton_clicked(NbtkButton * button , gpointer data)
{
    need_reload = TRUE;
    system("pinot-prefs &");
}


static void
buttons_click_event(NbtkButton* button , gpointer data)
{

  gchar * location=(gchar *)g_object_get_data(G_OBJECT(button),"location");
  
  if(g_str_has_prefix(location,"file://"))
   {
         gchar * command = g_strconcat(DEFAULT_FILE_MANAGER ,"  \"", location ,"\"&", NULL);
         system(command); 
         g_free(command);
   }

  else if(g_str_has_prefix(location,"http"))
   {
       gchar * command = g_strconcat( DEFAULT_BROWSER, "  \"" ,location ,"\"&" , NULL);
       system(command);
       g_free(command);
   }

}

static void hide_or_show_prev_next()
{
  if(simple_icon_view_has_prev_page( SIMPLE_ICON_VIEW(model_view[current].icon_view) ))
      clutter_actor_show(CLUTTER_ACTOR(button_prev));
  else
      clutter_actor_hide(CLUTTER_ACTOR(button_prev));

  if(simple_icon_view_has_next_page( SIMPLE_ICON_VIEW(model_view[current].icon_view) ))
      clutter_actor_show(CLUTTER_ACTOR(button_next));
  else
      clutter_actor_hide(CLUTTER_ACTOR(button_next));
}


static void change_page_number()
{

  if(model_view[current].result_number <= 0)
   {
      nbtk_button_set_label(NBTK_BUTTON(page_num_label),"");
     return;
   }
  gint page_number = simple_icon_view_get_page_number(SIMPLE_ICON_VIEW(model_view[current].icon_view)) + 1;
  char message[40];
  g_snprintf(message,40,"%s%u",_("show page "),page_number);
  nbtk_button_set_label(NBTK_BUTTON(page_num_label),message);
}

static void
on_SwitchButton_clicked(NbtkButton* button , gpointer data)
{
  gint i = GPOINTER_TO_INT(data);
  clutter_container_remove_actor(CLUTTER_CONTAINER (scroll), CLUTTER_ACTOR (model_view[current].icon_view));
  
  current = (ENGINE_UI)i;
  clutter_container_add (CLUTTER_CONTAINER (scroll), CLUTTER_ACTOR (model_view[current].icon_view), NULL);

  hide_or_show_prev_next();

  nbtk_button_set_label(NBTK_BUTTON(result_num_label),model_view[current].result_number_string);

  change_page_number();

  if(current == DESKTOP&& model_view[current].result_number >=2)
      clutter_actor_show(CLUTTER_ACTOR(sort_result_table));
  else
      clutter_actor_hide(CLUTTER_ACTOR(sort_result_table));
}

static void
on_prev_clicked(NbtkButton* button , gpointer data)
{
  simple_icon_view_set_prev_page(SIMPLE_ICON_VIEW(model_view[current].icon_view));
  hide_or_show_prev_next();
  change_page_number();
}

static void
on_next_clicked(NbtkButton* button , gpointer data)
{
   simple_icon_view_set_next_page(SIMPLE_ICON_VIEW(model_view[current].icon_view));
   hide_or_show_prev_next();
   change_page_number();
}

static void  set_result_number_per_page(gint number_page)
{
  int i;
  for(i=0;i<=DESKTOP;i++)
    {
     simple_icon_view_set_max_number(SIMPLE_ICON_VIEW (model_view[i].icon_view), number_page);
    }
}

static void init_model_view(gint window_width,gint window_height,gint number_page)
{

  int i;
  for(i=0;i<DESKTOP;i++)
  {
    model_view[i].type = (ENGINE_UI) i;
    model_view[i].model = clutter_list_model_new  (3, 
                                                   G_TYPE_STRING , "label",
                                                   G_TYPE_STRING , "tooltip",
                                                   G_TYPE_STRING , "location"
                                                   );

   model_view[i].icon_view = simple_icon_view_new();
   g_object_ref(model_view[i].icon_view);
   simple_icon_view_set_max_number(SIMPLE_ICON_VIEW (model_view[i].icon_view), number_page);
   simple_icon_view_set_model (SIMPLE_ICON_VIEW (model_view[i].icon_view), model_view[i].model);

   SimpleRenderer * renderer = (SimpleRenderer *)g_object_new (SIMPLE_TYPE_RENDERER,NULL);

   simple_renderer_set_actor_width( (SimpleRenderer *)renderer,window_width-50);
   simple_renderer_set_actor_height( (SimpleRenderer *)renderer,50);
   simple_icon_view_set_cell_renderer (SIMPLE_ICON_VIEW (model_view[i].icon_view), renderer);

   simple_icon_view_add_attribute (SIMPLE_ICON_VIEW (model_view[i].icon_view), "label", 0);
   simple_icon_view_add_attribute (SIMPLE_ICON_VIEW (model_view[i].icon_view), "tooltip-text", 1);
   simple_icon_view_add_attachdata (SIMPLE_ICON_VIEW (model_view[i].icon_view), "location", 2);
   simple_icon_view_set_callback_for_child(SIMPLE_ICON_VIEW (model_view[i].icon_view),(gpointer)buttons_click_event);
   model_view[i].button = nbtk_button_new_with_label(_(button_label[i]));
   model_view[i].result_number = 0;
   g_signal_connect( model_view[i].button,"clicked",G_CALLBACK(on_SwitchButton_clicked),GINT_TO_POINTER(i) );
  }

    i = DESKTOP;
    model_view[i].type = (ENGINE_UI) i;
    model_view[i].model = clutter_list_model_new (5, 
                                                  G_TYPE_STRING , "label",
                                                 // G_TYPE_STRING , "tooltip",
                                                  G_TYPE_STRING , "location",
                                                  G_TYPE_STRING , "date" ,
                                                  G_TYPE_STRING , "size" ,
                                                  G_TYPE_STRING , "type"
                                                  ); 

   model_view[i].icon_view = simple_icon_view_new();
   g_object_ref(model_view[i].icon_view);
   simple_icon_view_set_max_number(SIMPLE_ICON_VIEW (model_view[i].icon_view), number_page);
   simple_icon_view_set_model (SIMPLE_ICON_VIEW (model_view[i].icon_view), model_view[i].model);

   SimpleRenderer * renderer = (SimpleRenderer *)g_object_new (SIMPLE_TYPE_RENDERER,NULL);

   simple_renderer_set_actor_width( (SimpleRenderer *)renderer,window_width-50);
   simple_renderer_set_actor_height( (SimpleRenderer *)renderer,60);
   simple_icon_view_set_cell_renderer (SIMPLE_ICON_VIEW (model_view[i].icon_view), renderer);

   simple_icon_view_add_attribute (SIMPLE_ICON_VIEW (model_view[i].icon_view), "label", 0);
   simple_icon_view_add_attachdata (SIMPLE_ICON_VIEW (model_view[i].icon_view), "location", 1);
   simple_icon_view_set_callback_for_child(SIMPLE_ICON_VIEW (model_view[i].icon_view),(gpointer)buttons_click_event);

   model_view[i].button = nbtk_button_new_with_label(_(button_label[i]));
   model_view[i].result_number = 0;
   g_signal_connect( model_view[i].button,"clicked",G_CALLBACK(on_SwitchButton_clicked),GINT_TO_POINTER(i) );

}


static void init_category_table(NbtkWidget *category_table,gint width)
{
  int i;
  for(i=0;i<=DESKTOP;i++)
  {
   clutter_actor_set_name(CLUTTER_ACTOR(model_view[i].button),"cate_button");
   clutter_actor_set_size(CLUTTER_ACTOR(model_view[i].button),width,-1);
   nbtk_table_add_actor(NBTK_TABLE(category_table),CLUTTER_ACTOR(model_view[i].button),0,i); 
  }

}

static void init_result_status_table(NbtkWidget *result_status_table,gint width)
{

  button_prev = nbtk_button_new_with_label(_("prev"));
  clutter_actor_set_name(CLUTTER_ACTOR(button_prev),"prev_button");
  clutter_actor_set_size(CLUTTER_ACTOR(button_prev),60,-1);
  nbtk_table_add_actor(NBTK_TABLE(result_status_table),CLUTTER_ACTOR(button_prev),0,0);
  g_signal_connect(button_prev,"clicked",G_CALLBACK(on_prev_clicked),NULL); 

  result_num_label = nbtk_button_new();
  clutter_actor_set_name(CLUTTER_ACTOR(result_num_label),"button-static");
  clutter_actor_set_size(CLUTTER_ACTOR(result_num_label),(width-120)/2,-1);
  nbtk_table_add_actor(NBTK_TABLE(result_status_table),CLUTTER_ACTOR(result_num_label),0,1); 

  page_num_label = nbtk_button_new();
  clutter_actor_set_name(CLUTTER_ACTOR(page_num_label),"button-static");
  clutter_actor_set_size(CLUTTER_ACTOR(page_num_label),(width-120)/2,-1);
  nbtk_table_add_actor(NBTK_TABLE(result_status_table),CLUTTER_ACTOR(page_num_label),0,2); 

  button_next = nbtk_button_new_with_label(_("next"));
  clutter_actor_set_name(CLUTTER_ACTOR(button_next),"next_button");
  clutter_actor_set_size(CLUTTER_ACTOR(button_next),60,-1);
  nbtk_table_add_actor(NBTK_TABLE(result_status_table),CLUTTER_ACTOR(button_next),0,3);
  g_signal_connect(button_next,"clicked",G_CALLBACK(on_next_clicked),NULL);


}

static void init_sort_result_table(NbtkWidget *sort_result_table)
{
   NbtkWidget * sort_bydate_button = nbtk_button_new_with_label( _("date") );
   NbtkWidget * sort_bysize_button = nbtk_button_new_with_label( _("size") );
   NbtkWidget * sort_bytype_button = nbtk_button_new_with_label( _("type") ); 

   nbtk_table_add_actor(NBTK_TABLE(sort_result_table),CLUTTER_ACTOR(sort_bydate_button),0,1);
   nbtk_table_add_actor(NBTK_TABLE(sort_result_table),CLUTTER_ACTOR(sort_bysize_button),0,2);
   nbtk_table_add_actor(NBTK_TABLE(sort_result_table),CLUTTER_ACTOR(sort_bytype_button),0,3);

   g_signal_connect(G_OBJECT(sort_bydate_button), "clicked", G_CALLBACK(set_sort), GINT_TO_POINTER(0));
   g_signal_connect(G_OBJECT(sort_bysize_button), "clicked", G_CALLBACK(set_sort), GINT_TO_POINTER(1));
   g_signal_connect(G_OBJECT(sort_bytype_button), "clicked", G_CALLBACK(set_sort), GINT_TO_POINTER(2));

   clutter_actor_set_name(CLUTTER_ACTOR(sort_bydate_button), "button-common");
   clutter_actor_set_name(CLUTTER_ACTOR(sort_bysize_button), "button-common");
   clutter_actor_set_name(CLUTTER_ACTOR(sort_bytype_button), "button-common");  
 
}



int create_and_show()
{
  init_thread_environment();

  gint window_width;
  gint window_height;
  NbtkWidget * input_entry;
  NbtkWidget * find_button;
  NbtkWidget * prefs_button;
  GError * error = NULL;
  GtkWidget * window;
  GtkWidget * vbox;
  GtkWidget * clutter_widget;
  GdkScreen * screen;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(on_window_destroy),NULL);

  screen = gdk_screen_get_default();
  window_width = gdk_screen_get_width( screen );
  window_height = gdk_screen_get_height( screen ); 

  gtk_window_set_title(GTK_WINDOW(window),"pinot");


    clutter_widget = gtk_clutter_embed_new (); 
    gtk_container_add (GTK_CONTAINER (window), clutter_widget);
    gtk_widget_show(clutter_widget);

    ClutterActor *stage;
    ClutterColor stage_color = { 0x61 , 0x61 , 0x1a , 0xff } ;

  if(! nbtk_style_load_from_file (nbtk_style_get_default(), DEFAULT_CSS_PATH , &error) )
   {
     printf ( "Unable to read file: %s\n", error->message);
   }

  stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (clutter_widget));
  clutter_stage_set_color ( CLUTTER_STAGE(stage) , &stage_color ) ;

/*search entry and button*/
  input_entry = nbtk_entry_new("");
  clutter_stage_set_key_focus (CLUTTER_STAGE (stage), CLUTTER_ACTOR(input_entry));

  find_button = nbtk_button_new_with_label(_("search"));
  prefs_button = nbtk_button_new_with_label(_("setting"));

  clutter_actor_set_name(CLUTTER_ACTOR(find_button),"desktop-button");
  clutter_actor_set_name(CLUTTER_ACTOR(prefs_button),"desktop-button");

  NbtkWidget * top_table = nbtk_table_new();

  clutter_actor_set_name(CLUTTER_ACTOR(top_table), "top-table");
  clutter_actor_set_size(CLUTTER_ACTOR (top_table) , -1 , 30);
  clutter_actor_set_position(CLUTTER_ACTOR (top_table) , 10 , 10);
  
  clutter_container_add_actor( CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (top_table) );
  clutter_actor_show(CLUTTER_ACTOR(top_table));

  nbtk_table_set_col_spacing( NBTK_TABLE(top_table) , 5);

  clutter_actor_set_size(CLUTTER_ACTOR (input_entry) , window_width/2 , -1);

  nbtk_table_add_actor(NBTK_TABLE(top_table), CLUTTER_ACTOR(input_entry), 0, 1);
  nbtk_table_add_actor(NBTK_TABLE(top_table), CLUTTER_ACTOR(find_button), 0, 2);
  nbtk_table_add_actor(NBTK_TABLE(top_table), CLUTTER_ACTOR(prefs_button), 0, 3);

  g_signal_connect(prefs_button,"clicked",G_CALLBACK(on_prefsButton_clicked),NULL);  
  g_signal_connect(find_button,"clicked",G_CALLBACK(on_findButton_clicked),input_entry);

  init_model_view(window_width,window_height,m_settings.m_maxresultperpagenumbers);

  NbtkWidget * category_table = nbtk_table_new();
  init_category_table(category_table,70);
  NbtkWidget * result_status_table = nbtk_table_new();
  init_result_status_table(result_status_table,window_width-30);
  sort_result_table = nbtk_table_new(); 
  init_sort_result_table(sort_result_table);
  
  clutter_actor_set_name(CLUTTER_ACTOR(category_table),"cate_table");
  clutter_actor_set_size(CLUTTER_ACTOR (category_table) , 300 , 30);
  clutter_actor_set_position( CLUTTER_ACTOR(category_table), 10,60);
  clutter_container_add_actor( CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (category_table) );

  NbtkWidget *big_table = nbtk_table_new();
  nbtk_table_set_row_spacing(NBTK_TABLE(big_table),5);
  clutter_actor_set_name(CLUTTER_ACTOR(big_table),"big_table");
  clutter_actor_set_size(CLUTTER_ACTOR (big_table) , window_width-20 , window_height-130);
  clutter_actor_set_position( CLUTTER_ACTOR(big_table), 10,90);
  clutter_container_add_actor( CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (big_table) );

  clutter_actor_set_name(CLUTTER_ACTOR(result_status_table),"rst_table");
  clutter_actor_set_size(CLUTTER_ACTOR (result_status_table) , -1 , 30);
  nbtk_table_add_actor(NBTK_TABLE(big_table), CLUTTER_ACTOR(result_status_table), 0, 0);

  NbtkWidget * clip_table = nbtk_table_new();
  nbtk_table_set_col_spacing(NBTK_TABLE(clip_table),10);
  
  scroll = (NbtkWidget *) nbtk_scroll_view_new ();
  clutter_actor_set_size( CLUTTER_ACTOR(scroll), -1 ,window_height-177);

  nbtk_table_add_actor(NBTK_TABLE(clip_table), CLUTTER_ACTOR(scroll), 0, 1);
  nbtk_table_add_actor(NBTK_TABLE(big_table), CLUTTER_ACTOR(clip_table), 1, 0);

  NbtkWidget * clip_table_2 = nbtk_table_new();
  clutter_actor_set_size( CLUTTER_ACTOR(clip_table_2), -1 , 10);
  nbtk_table_add_actor(NBTK_TABLE(big_table), CLUTTER_ACTOR(clip_table_2), 2, 0);

  clutter_actor_set_position( CLUTTER_ACTOR(sort_result_table), window_width-220,window_height-80);
  clutter_container_add_actor( CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (sort_result_table) );
    
  clutter_container_add (CLUTTER_CONTAINER (scroll), CLUTTER_ACTOR (model_view[DESKTOP].icon_view), NULL);
  current = DESKTOP;

    gtk_widget_show_all(GTK_WIDGET(window));   
    clutter_actor_show_all(stage);
    clutter_actor_hide(CLUTTER_ACTOR(button_prev));
    clutter_actor_hide(CLUTTER_ACTOR(button_next));
    clutter_actor_hide(CLUTTER_ACTOR(sort_result_table));
 
   gtk_main();
  
  return EXIT_SUCCESS;
}

static void update_model( ENGINE_UI type, const vector<DocumentInfo> &resultsList, const string &resultsCharset)
{

  ClutterModel * model = model_view[type].model;
  NbtkWidget   * view  = model_view[type].icon_view;
  char message[40];
/*remove all things*/

  simple_icon_view_freeze ((SimpleIconView *)view);  

    ClutterModelIter * iter = clutter_model_get_last_iter (model); 
    gint row;
    while(iter && !clutter_model_iter_is_first(iter))
     {
        row = clutter_model_iter_get_row(iter);
        clutter_model_iter_prev(iter);
        clutter_model_remove(model, row);
     }
       row = clutter_model_iter_get_row(iter);
       clutter_model_remove(model, row);

    simple_icon_view_set_first_page((SimpleIconView *)view);
    simple_icon_view_thaw ((SimpleIconView *)view);

    simple_icon_view_freeze ((SimpleIconView *)view);
   if(model_view[type].result_number_string != NULL)
            g_free(model_view[type].result_number_string);
   g_snprintf(message, 40, "%s%s%d",_(button_label[type]), _("result number is:"), resultsList.size() );

   model_view[type].result_number_string = g_strdup(message);   
   model_view[type].result_number = resultsList.size();
   for (vector<DocumentInfo>::const_iterator resultIter = resultsList.begin();
		resultIter != resultsList.end(); ++resultIter)
   {
        ustring title(to_utf8(resultIter->getTitle(), resultsCharset));
        ustring location(to_utf8(resultIter->getLocation(true), resultsCharset));
        ustring timestamp(to_utf8(resultIter->getTimestamp()));
        ustring extract(to_utf8(resultIter->getExtract(), resultsCharset));
        float currentScore = resultIter->getScore();

      if(type < DESKTOP)
           {
            char * tip_title = _("title:");
            char * tip_location = _("url:");
            char * tip_extract = _("Extract:");
            if(extract=="")
                 extract=_("no extract");
                
            gchar * label = g_strconcat(tip_title, title.c_str(),"   " , 
                                        tip_location, location.c_str(),"\n",
                                        tip_extract, extract.c_str(),NULL );
            const char * tooltip = location.c_str() ; 
            clutter_model_append (model, 0, label ,
                                     1, tooltip ,
                                     2, location.c_str(),
                                    -1);
 
              g_free(label);
             
	   
           }
       else
           {
            
            Url urlObj(resultIter->getLocation());
	    string type = MIMEScanner::scanUrl(urlObj);                  
 
            off_t size = resultIter->getSize();
            off_t tsize = size;  
            char * tip_title = _("Name:");
            char * tip_format = _("Format:");
            char * tip_size_end;
            int size_kind = B;
            while(size >= 1024 && size_kind < TB)
             {
               size = size/1024;
               size_kind ++ ;
             }

            tip_size_end = size_end[size_kind];

            char * tip_size = _("Size:");
            char * tip_date = _("Date:");
            char * tip_extract = _("Extract:");
            char size_str1[64];
            char size_str2[64];
            g_snprintf(size_str1,64,"%u",size);
            g_snprintf(size_str2,64,"%u",tsize);                     

            printf("size showd is %s,real is %s\n",size_str1,size_str2); 
 
            if(extract=="")
                 extract=_("blank file");

            
            gchar * label = g_strconcat(tip_title, title.c_str(),"   ", 
                                        tip_format, type.c_str(),"\n" ,
                                        tip_size , size_str1, tip_size_end ,"  ",
                                        tip_date , timestamp.c_str(),"\n",
                                        tip_extract , extract.c_str(),
                                        NULL );
            
           const char * tooltip = extract.c_str() ;
           
            clutter_model_append (model, 0, label ,
                                     /* 1, tooltip ,*/
                                     1, location.c_str(),
                                     2, timestamp.c_str(),
                                     3, size_str2,
                                     4, type.c_str() ,
                             -1);
             g_free(label);
           }
 
     }

  simple_icon_view_thaw ((SimpleIconView *)view);

  on_SwitchButton_clicked(NULL,GINT_TO_POINTER(current));
}
/*******************sort function*************************************************/
static gint sort_bydate (ClutterModel *model, const GValue *a, const GValue *b, gpointer user_data)
{
/*
 This is not OK,FIX LATER!!!
*/
  g_assert ( G_VALUE_HOLDS_STRING(a) ) ;
  g_assert ( G_VALUE_HOLDS_STRING(b) ) ;

   const gchar * byte_a = g_value_get_string(a);
   const gchar * byte_b = g_value_get_string(b);

  int result = g_strcmp0( byte_a, byte_b);
  
  gint sort_direct = GPOINTER_TO_INT (user_data) ;
  
   if(sort_direct == 0 )
      return result ;
   else
      return 0-result; 
}

static gint sort_bysize (ClutterModel *model, const GValue *a, const GValue *b, gpointer user_data)
{

  g_assert( G_VALUE_HOLDS_STRING(a) );
  g_assert( G_VALUE_HOLDS_STRING(b) );

   const gchar * size_a = g_value_get_string(a);
   const gchar * size_b = g_value_get_string(b);

   gint result = atol(size_a) - atol(size_b) ;
 
   if(result > 0 ) result = 1;
   else if(result < 0 ) result = -1;

   gint sort_direct = GPOINTER_TO_INT (user_data) ;
   
   if(sort_direct == 0 )
      return result ;
   else 
      return 0-result;

}

static gint sort_bytype (ClutterModel *model, const GValue *a, const GValue *b, gpointer user_data)
{
  g_assert ( G_VALUE_HOLDS_STRING(a) ) ;
  g_assert ( G_VALUE_HOLDS_STRING(b) ) ;

   const gchar * byte_a = g_value_get_string(a);
   const gchar * byte_b = g_value_get_string(b);

  int result = g_strcmp0( byte_a, byte_b);

  gint sort_direct = GPOINTER_TO_INT (user_data) ;

   if(sort_direct == 0 )
      return result ;
   else 
      return 0-result;

}

static void
set_sort (NbtkButton *button, gpointer data)
{

static int date_dir=1;
static int size_dir=1;
static int type_dir=1;

  int a = GPOINTER_TO_INT(data); 

  switch (a)
  {
   case 0:
        if( date_dir!=0 )  
            date_dir=0;
        else        
            date_dir=1;
        clutter_model_set_sort (model_view[DESKTOP].model , 2 , sort_bydate, GINT_TO_POINTER(date_dir), NULL);
        break;
   case 1:
        if( size_dir!=0 )
            size_dir=0;
        else
            size_dir=1;
        clutter_model_set_sort (model_view[DESKTOP].model , 3 , sort_bysize, GINT_TO_POINTER(size_dir), NULL);
        break;
   case 2:
        if( type_dir!=0 )
            type_dir=0;
        else
            type_dir=1;
        clutter_model_set_sort (model_view[DESKTOP].model , 4 , sort_bytype, GINT_TO_POINTER(type_dir), NULL);
        break;
   default:
        break;
  } 
}

